home *** CD-ROM | disk | FTP | other *** search
/ A.C.E. 3 / ACE CD 3.iso / files / utils / aplay200.lha / APlayer / Files / Developer.lha / Examples / apSoundMon20Library.S < prev    next >
Text File  |  1995-12-23  |  25KB  |  1,119 lines

  1. ; $VER: SoundMon20.library 3.0
  2. ;
  3.  
  4.     INCDIR    "Includes3.0:Include3.0/"
  5.     INCLUDE    "Exec/Types.i"
  6.     INCLUDE    "Own/SystemBases.i"
  7.     INCLUDE    "Own/SystemStructures.i"
  8.     INCLUDE    "Own/SystemOffsets.i"
  9.     INCLUDE    "Own/AccessiblePlayer.i"
  10.  
  11.  
  12. VERSION        =    3
  13. REVISION    =    0
  14.  
  15. TRUE        =    -1
  16. FALSE        =    0
  17.  
  18. ; Library Data
  19.  
  20. LN_Name        =    10
  21. LN_Type        =    8
  22. NT_Library    =    9
  23.  
  24. LIBB_Summing    =    0
  25. LIBB_Changed    =    1
  26. LIBB_SumUsed    =    2
  27. LIBB_DelExp    =    3
  28.  
  29. LIBF_Summing    =    1<<LIBB_Summing
  30. LIBF_Changed    =    1<<LIBB_Changed
  31. LIBF_SumUsed    =    1<<LIBB_SumUsed
  32. LIBF_DelExp    =    1<<LIBB_DelExp
  33.  
  34. ; Macros
  35.  
  36. INBYTE    MACRO
  37.     dc.b    %11100000,0
  38.     dc.w    \1
  39.     dc.b    \2,0
  40.     ENDM
  41.  
  42. INWORD    MACRO
  43.     dc.b    %11010000,0
  44.     dc.w    \1,\2
  45.     ENDM
  46.  
  47. INLONG    MACRO
  48.     dc.b    %11000000,0
  49.     dc.w    \1
  50.     dc.l    \2
  51.     ENDM
  52.  
  53. ; Library Base Structure
  54.  
  55.     STRUCTURE LibraryStruct,0
  56.     STRUCT    LIB_Node,14
  57.     UBYTE    LIB_Flags
  58.     UBYTE    LIB_Pad
  59.     UWORD    LIB_NegSize
  60.     UWORD    LIB_PosSize
  61.     UWORD    LIB_Version
  62.     UWORD    LIB_Revision
  63.     APTR    LIB_IDString
  64.     ULONG    LIB_Sum
  65.     UWORD    LIB_OpenCnt
  66.  
  67.     LONG    LIB_SegList
  68.     LABEL    LibraryStruct_SIZEOF
  69.  
  70.  
  71.     SECTION    SoundMon20.library,CODE
  72.  
  73. START    moveq    #0,d0
  74.     rts
  75. ;------------------------------------------------------------------------------
  76. LIBNAME    dc.b    "apSoundMon20.library",0
  77.  
  78. LIBID    dc.b    "SoundMon20.library 3.0 (5-December-1995)",0
  79.     even
  80. ;------------------------------------------------------------------------------
  81. ; ROMTAG Structure
  82. ;
  83.  
  84. ROMTAG    dc.w    $4afc            ;ROMTAG Indentifier
  85.     dc.l    romtag
  86.     dc.l    slut
  87.     dc.b    $80            ;Flags
  88.     dc.b    version
  89.     dc.b    $09            ;Type Of Module
  90.     dc.b    $00            ;Initialization Priority
  91.     dc.l    libname
  92.     dc.l    libid
  93.     dc.l    autinit            ;Pointer To AUTOINIT Table
  94. ;------------------------------------------------------------------------------
  95. ; AUTOINIT Table
  96. ;
  97.  
  98. AUTINIT    dc.l    LibraryStruct_SIZEOF    ;Size Of Structure AFTER Base Address
  99.     dc.l    vector            ;Pointer To Vector Table
  100.     dc.l    inittab            ;Pointer To Init Structure
  101.     dc.l    init            ;Pointer To Init Routine
  102. ;------------------------------------------------------------------------------
  103. ; Init Table
  104. ;
  105.  
  106. INITTAB    INBYTE    LN_Type,NT_Library
  107.     INBYTE    LIB_Flags,LIBF_SumUsed!LIBF_Changed
  108.     INWORD    LIB_Version,version
  109.     INWORD    LIB_Revision,revision
  110.     INLONG    LN_Name,libname
  111.     INLONG    LIB_IDString,libid
  112.     dc.l    0
  113. ;------------------------------------------------------------------------------
  114. ; Vector Table
  115. ;
  116.  
  117. VECTOR    dc.w    -1
  118.     dc.w    opnlib-vector,clslib-vector,expunge-vector,extfunc-vector
  119.     dc.w    SM_GetTags-vector
  120.     dc.w    -1
  121. ;------------------------------------------------------------------------------
  122. ; Init Routine
  123. ;
  124.  
  125. INIT    movem.l    d1-d7/a0-a6,-(sp)
  126.     move.l    d0,a4            ;Base Address
  127.     move.l    a0,LIB_SegList(a4)
  128.  
  129.     move.l    a4,d0
  130.     movem.l    (sp)+,d1-d7/a0-a6
  131.     rts
  132. ;------------------------------------------------------------------------------
  133. ; Offset  -6: Open Library
  134. ;
  135.  
  136. OPNLIB    addq.w    #1,LIB_OpenCnt(a6)
  137.     bclr    #LIBB_DelExp,LIB_Flags(a6)
  138.     move.l    a6,d0
  139.     rts
  140. ;------------------------------------------------------------------------------
  141. ; Offset -12: Close Library
  142. ;
  143.  
  144. CLSLIB    moveq    #0,d0
  145.     subq.w    #1,LIB_OpenCnt(a6)
  146.     bne.b    clslibo
  147.     btst    #LIBB_DelExp,LIB_Flags(a6)
  148.     bne.b    expunge
  149. CLSLIBO    rts
  150. ;------------------------------------------------------------------------------
  151. ; Offset -18: Expunge
  152. ;
  153.  
  154. EXPUNGE    movem.l    d1-d7/a0-a6,-(sp)
  155.     move.l    a6,a4
  156.     tst.w    LIB_OpenCnt(a4)
  157.     beq.b    exp1
  158.     bset    #LIBB_DelExp,LIB_Flags(a4)
  159.     moveq    #0,d0
  160.     bra.b    expungo
  161.  
  162. EXP1    move.l    4.w,a6
  163.     move.l    LIB_SegList(a4),d2
  164.     move.l    a4,a1
  165.     jsr    Remove(a6)
  166.  
  167.     move.l    a4,a1
  168.     moveq    #0,d0
  169.     move.w    LIB_NegSize(a4),d0
  170.     sub.l    d0,a1
  171.     add.w    LIB_PosSize(a4),d0
  172.     jsr    FreeMem(a6)
  173.     move.l    d2,d0
  174.  
  175. EXPUNGO    movem.l    (sp)+,d1-d7/a0-a6
  176.     rts
  177. ;------------------------------------------------------------------------------
  178. ; Offset -24: ExtFunc
  179. ;
  180.  
  181. EXTFUNC    moveq    #0,d0
  182.     rts
  183. ;------------------------------------------------------------------------------
  184. ;******************************************************************************
  185. ;* Sound Monitor 2.0 Player
  186. ;******************************************************************************
  187. ;------------------------------------------------------------------------------
  188. ; Structure
  189. ;
  190.  
  191.     STRUCTURE SoundMonStruct,0
  192.     APTR    SMON_Global
  193.     APTR    SMON_NoteStruct
  194.     APTR    SMON_Module
  195.     APTR    SMON_Tables
  196.     UWORD    SMON_DMA
  197.     UWORD    SMON_BPStep
  198.     UBYTE    SMON_NumTables
  199.     UBYTE    SMON_ArpCount
  200.     UBYTE    SMON_BPCount
  201.     UBYTE    SMON_BPDelay
  202.     UBYTE    SMON_ST
  203.     UBYTE    SMON_TR
  204.     UBYTE    SMON_BPPatCount
  205.     UBYTE    SMON_BPRepCount
  206.     STRUCT    SMON_Samples,15*4
  207.     STRUCT    SMON_BPCurrent,14+18+32*3
  208.     STRUCT    SMON_BPBuffer,144
  209.     LABEL    SoundMonStruct_SIZEOF
  210. ;------------------------------------------------------------------------------
  211. ; Offset -30: GetTags
  212. ;
  213. ; IN :    Nothing
  214. ;
  215. ; OUT:    A0 = Pointer To A TagList
  216. ;
  217.  
  218. SM_GetTags
  219.     lea    SM_Tags(pc),a0
  220.     rts
  221.  
  222. SM_Tags    dc.l    APT_RequestVersion,6
  223.     dc.l    APT_EarlyCheck,SM_TestModule
  224.     dc.l    APT_NotePlayer,SM_NotePlayer
  225.     dc.l    APT_DefaultPlayerInfo,SM_DefaultPlayerInfo
  226.     dc.l    APT_UsedChannels,SM_UsedChannels
  227.  
  228.     dc.l    APT_InitPlayer,SM_InitPlayer
  229.     dc.l    APT_EndPlayer,SM_EndPlayer
  230.     dc.l    APT_InitSound,SM_InitSound
  231.     dc.l    APT_EndSound,SM_EndSound
  232.     dc.l    APT_Interrupt,SM_PlayModule
  233.  
  234.     dc.l    APT_PlayerName,smname
  235.     dc.l    APT_Description,smdes
  236.     dc.l    APT_ModuleName,SM_ModuleName
  237.     dc.l    APT_Pause,TRUE
  238.  
  239.     dc.l    APT_GetMaxPattern,SM_GetMaxPattern
  240.     dc.l    APT_GetMaxSample,SM_GetMaxSample
  241.     dc.l    APT_GetSongLength,SM_GetSongLength
  242.  
  243.     dc.l    APT_GetSongPos,SM_GetSongPos
  244.     dc.l    APT_Rewind,SM_Rewind
  245.     dc.l    APT_Forward,SM_Forward
  246.     dc.l    TAG_END
  247.  
  248. SMNAME    dc.b    "Sound Monitor 2.0",0
  249. SMDES    dc.b    "Original player by Brian Postma.",10
  250.     dc.b    "Adapted by Tax.",10,10
  251.     dc.b    "This player uses a NotePlayer.",0
  252.     even
  253. ;------------------------------------------------------------------------------
  254. ; TestModule
  255. ;
  256. ; IN :    Nothing
  257. ;
  258. ; OUT:    D0 = Success (0=Unknown, 1=Ok, 2=Error)
  259. ;
  260.  
  261. SM_TestModule
  262.     movem.l    d1-d2/a0/a4-a5,-(sp)
  263.  
  264.     subq.l    #4,sp
  265.     moveq    #$1a,d1
  266.     moveq    #4,d2
  267.     move.l    sp,a0
  268.     move.l    APG_CheckLoad(a5),a4
  269.     jsr    (a4)            ;Read Mark
  270.     move.l    (sp)+,d1
  271.     tst.l    d0
  272.     beq.b    .tsmod1
  273.  
  274.     moveq    #0,d0            ;Unknown
  275.     lsr.l    #8,d1
  276.     cmp.l    #"V.2",d1
  277.     bne.b    .tsmodo
  278.     moveq    #1,d0            ;Ok
  279.     bra.b    .tsmodo
  280.  
  281. .TSMOD1    moveq    #2,d0            ;Error
  282. .TSMODO    movem.l    (sp)+,d1-d2/a0/a4-a5
  283.     rts
  284. ;------------------------------------------------------------------------------
  285. ; NotePlayer
  286. ;
  287. ; IN :    A1 = Address
  288. ;
  289. ; OUT:    A0 = Pointer To Info Table
  290. ;
  291.  
  292. SM_NotePlayer
  293. SM_DefaultPlayerInfo
  294.     lea    .nottab(pc),a0
  295.     rts
  296.  
  297. .NOTTAB    dc.w    ANF_Signed
  298.     dc.b    4,8,0
  299.     even
  300. ;------------------------------------------------------------------------------
  301. ; UsedChannels
  302. ;
  303. ; IN :    A1 = Address
  304. ;
  305. ; OUT:    D1 = Used Channels
  306. ;
  307.  
  308. SM_UsedChannels
  309.     moveq    #4,d1
  310.     rts
  311. ;------------------------------------------------------------------------------
  312. ; InitPlayer
  313. ;
  314. ; IN :    A1 = Address
  315. ;
  316. ; OUT:    D1 = Success (0=Error)
  317. ;
  318.  
  319. SM_InitPlayer
  320.     movem.l    d0/a0,-(sp)
  321.     move.l    APG_AllocChannels(a5),a0
  322.     jsr    (a0)
  323.     move.l    d0,d1
  324.     movem.l    (sp)+,d0/a0
  325.     rts
  326. ;------------------------------------------------------------------------------
  327. ; EndPlayer
  328. ;
  329. ; IN :    A1 = Address
  330. ;
  331. ; OUT:    Nothing
  332. ;
  333.  
  334. SM_EndPlayer
  335.     move.l    a0,-(sp)
  336.     move.l    APG_FreeChannels(a5),a0
  337.     jsr    (a0)
  338.     move.l    (sp)+,a0
  339.     rts
  340. ;------------------------------------------------------------------------------
  341. ; InitSound
  342. ;
  343. ; IN :    A1 = Address
  344. ;
  345. ; OUT:    Nothing
  346. ;
  347.  
  348. SM_InitSound    movem.l    d0-d2/a0-a1/a4,-(sp)
  349.         lea    SM_DataArea,a4
  350.         move.l    a1,SMON_Module(a4)
  351.         move.l    a5,SMON_Global(a4)
  352.         move.l    APG_ChannelInfo(a5),SMON_NoteStruct(a4)
  353.  
  354.         move.b    #1,SMON_ArpCount(a4)
  355.         move.b    #1,SMON_BPCount(a4)
  356.         move.b    #6,SMON_BPDelay(a4)
  357.         move.b    #1,SMON_BPRepCount(a4)
  358.  
  359.         clr.w    SMON_DMA(a4)
  360.         clr.w    SMON_BPStep(a4)
  361.         clr.b    SMON_BPPatCount(a4)
  362.         clr.b    SMON_ST(a4)
  363.         clr.b    SMON_TR(a4)
  364.  
  365.         lea    SMON_BPCurrent(a4),a0
  366.         move.l    APG_NullSample(a5),a1
  367.         clr.l    (a0)+
  368.         move.l    a1,(a0)+
  369.         move.w    #1,(a0)+
  370.         clr.l    (a0)+
  371.  
  372.         clr.l    (a0)+
  373.         clr.l    (a0)+
  374.         clr.l    (a0)+
  375.         clr.w    (a0)+
  376.         clr.w    (a0)+
  377.         clr.w    (a0)+
  378.  
  379.         moveq    #3-1,d0
  380. .initloop    clr.l    (a0)+
  381.         move.l    a1,(a0)+
  382.         move.w    #1,(a0)+
  383.         clr.l    (a0)+
  384.         clr.l    (a0)+
  385.         clr.l    (a0)+
  386.         clr.l    (a0)+
  387.         clr.l    (a0)+
  388.         clr.w    (a0)+
  389.         dbra    d0,.initloop
  390.  
  391.         lea    SMON_BPBuffer(a4),a0
  392.         moveq    #(144/2)-1,d0
  393. .initloop1    clr.w    (a0)+
  394.         dbra    d0,.initloop1
  395.  
  396.         lea    SMON_Samples(a4),a0
  397.         move.l    SMON_Module(a4),a1
  398.  
  399.         clr.b    SMON_NumTables(a4)
  400.         cmp.w    #'V.',26(a1)
  401.         bne.b    bpnotv2
  402.         cmp.b    #'2',28(a1)
  403.         bne.b    bpnotv2
  404.         move.b    29(a1),SMON_NumTables(a4)
  405.  
  406. bpnotv2        move.l    #512,d0
  407.         move.w    30(a1),d1    ;d1 now contains length in steps
  408.         moveq    #1,d2        ;1 is highest pattern number
  409.         mulu    #4,d1        ;4 voices per step
  410.         subq.w    #1,d1        ;correction for DBRA
  411. findhighest    cmp.w    (a1,d0.w),d2    ;Is it higher
  412.         bge.b    nothigher    ;No
  413.         move.w    (a1,d0.w),d2    ;Yes, so let D2 be highest
  414. nothigher    addq.l    #4,d0        ;Next Voice
  415.         dbra    d1,findhighest    ;And search
  416.  
  417.         move.w    30(a1),d1
  418.         lsl.w    #4,d1        ;16 bytes per step
  419.         move.l    #512,d0        ;header is 512 bytes
  420.         mulu    #48,d2        ;48 bytes per pattern
  421.         add.l    d2,d0
  422.         add.l    d1,d0        ;offset for samples
  423.         add.l    SMON_Module(a4),d0
  424.         move.l    d0,SMON_Tables(a4)
  425.         moveq    #0,d1
  426.         move.b    SMON_NumTables(a4),d1    ;Number of tables
  427.         lsl.l    #6,d1            ;x 64
  428.         add.l    d1,d0
  429.  
  430.         moveq    #15-1,d1    ;15 samples
  431.         lea    32(a1),a1
  432. initloop    move.l    d0,(a0)+
  433.         cmp.b    #$ff,(a1)
  434.         beq.b    bpissynth
  435.         move.w    24(a1),d2
  436.         add.w    d2,d2
  437.         add.l    d2,d0        ;offset next sample
  438. bpissynth    lea    32(a1),a1    ;Length of Sample Part in header
  439.         dbra    d1,initloop
  440.  
  441.         movem.l    (sp)+,d0-d2/a0-a1/a4
  442.         rts
  443. ;------------------------------------------------------------------------------
  444. ; EndSound
  445. ;
  446. ; IN :    A1 = Address
  447. ;
  448. ; OUT:    Nothing
  449. ;
  450.  
  451. SM_EndSound
  452.     rts
  453. ;------------------------------------------------------------------------------
  454. ; PlayModule
  455. ;
  456. ; IN :    A1 = Address
  457. ;    D1 = VBlank/Cia (0=CIA)
  458. ;
  459. ; OUT:    Nothing
  460. ;
  461.  
  462. SM_PlayModule    movem.l    d0-d7/a0-a6,-(sp)
  463.         lea    SM_DataArea,a5
  464.         bsr.b    bpmusic
  465.  
  466.         move.l    SMON_Global(a5),a5
  467.         move.l    APG_NotePlayer(a5),a5
  468.         jsr    (a5)
  469.         movem.l    (sp)+,d0-d7/a0-a6
  470.         rts
  471.  
  472. bpmusic        bsr.w    bpsynth
  473.         subq.b    #1,SMON_ArpCount(a5)
  474.         moveq    #3,d0
  475.         lea    SMON_BPCurrent(a5),a0
  476.         move.l    SMON_NoteStruct(a5),a1
  477. bploop1        move.b    12(a0),d4
  478.         ext.w    d4
  479.         add.w    d4,(a0)
  480.         tst.b    $1e(a0)
  481.         bne.b    bplfo
  482.         move.w    (a0),NPC_Period(a1)
  483.         bset    #NPCFB_Period,(a1)
  484.  
  485. bplfo        tst.b    11(a0)
  486.         bne.b    bpdoarp
  487.         tst.b    13(a0)
  488.         beq.b    not2
  489. bpdoarp        tst.b    SMON_ArpCount(a5)
  490.         bne.b    not0
  491.         move.b    11(a0),d3
  492.         move.b    13(a0),d4
  493.         and.w    #240,d4
  494.         and.w    #240,d3
  495.         lsr.w    #4,d3
  496.         lsr.w    #4,d4
  497.         add.w    d3,d4
  498.         add.b    10(a0),d4
  499.         bsr.w    bpplayarp
  500.         bra.b    not2
  501.  
  502. not0        cmp.b    #1,SMON_ArpCount(a5)
  503.         bne.b    not1
  504.         move.b    11(a0),d3
  505.         move.b    13(a0),d4
  506.         and.w    #15,d3
  507.         and.w    #15,d4
  508.         add.w    d3,d4
  509.         add.b    10(a0),d4
  510.         bsr.w    bpplayarp
  511.         bra.b    not2
  512.  
  513. not1        move.b    10(a0),d4
  514.         bsr.w    bpplayarp
  515. not2        lea    NPChannel_SIZEOF(a1),a1
  516.         lea    $20(a0),a0
  517.         dbra    d0,bploop1
  518.  
  519.         tst.b    SMON_ArpCount(a5)
  520.         bne.b    arpnotzero
  521.         move.b    #3,SMON_ArpCount(a5)
  522. arpnotzero    subq.b    #1,SMON_BPCount(a5)
  523.         beq.b    bpskip1
  524.         rts
  525.  
  526. bpskip1        move.b    SMON_BPDelay(a5),SMON_BPCount(a5)
  527. bpplay        bsr.b    bpnext
  528.  
  529.         moveq    #3,d0
  530.         move.l    SMON_NoteStruct(a5),a1
  531.         moveq    #1,d1
  532.         move.l    a5,-(sp)
  533.         lea    SMON_BPCurrent(a5),a2
  534.         lea    SMON_BPBuffer(a5),a5
  535. bploop2        btst    #15,(a2)
  536.         beq.b    bpskip7
  537.         bsr.w    bpplayit
  538. bpskip7        asl.w    #1,d1
  539.         lea    NPChannel_SIZEOF(a1),a1
  540.         lea    $20(a2),a2
  541.         lea    $24(a5),a5
  542.         dbra    d0,bploop2
  543.         move.l    (sp)+,a5
  544.         rts
  545.  
  546. bpnext        clr.w    SMON_DMA(a5)
  547.         move.l    SMON_Module(a5),a0
  548.         move.l    SMON_NoteStruct(a5),a3
  549.         moveq    #3,d0
  550.         moveq    #1,d7
  551.         lea    SMON_BPCurrent(a5),a1
  552. bploop3        moveq    #0,d1
  553.         move.w    SMON_BPStep(a5),d1
  554.         lsl.w    #4,d1
  555.         move.l    d0,d2
  556.         lsl.l    #2,d2
  557.         add.l    d2,d1
  558.         add.l    #512,d1
  559.         move.w    (a0,d1.w),d2
  560.         move.b    2(a0,d1.w),SMON_ST(a5)
  561.         move.b    3(a0,d1.w),SMON_TR(a5)
  562.         subq.w    #1,d2
  563.         mulu    #48,d2
  564.         moveq    #0,d3
  565.         move.w    30(a0),d3
  566.         lsl.w    #4,d3
  567.         add.l    d2,d3
  568.         move.l    #512,d4
  569.         move.b    SMON_BPPatCount(a5),d4
  570.         add.l    d3,d4
  571.         move.l    d4,a2
  572.         add.l    a0,a2
  573.         moveq    #0,d3 
  574.         move.b    (a2),d3
  575.         tst.b    d3
  576.         bne.b    bpskip4
  577.         bra.w    bpoptionals
  578.  
  579. bpskip4        clr.w    12(a1)            ;Clear autoslide/autoarpeggio
  580.         move.b    1(a2),d4
  581.         and.b    #15,d4
  582.         cmp.b    #10,d4            ;Option 10->transposes off
  583.         bne.b    bp_do1
  584.         move.b    2(a2),d4
  585.         and.b    #240,d4              ;Higher nibble=transpose
  586.         bne.b    bp_not1
  587. bp_do1        add.b    SMON_TR(a5),d3
  588.         ext.w    d3
  589. bp_not1        move.b    d3,10(a1)         ;Voor Arpeggio's
  590.         lea    bpper(pc),a4
  591.         lsl.w    #1,d3
  592.         move.w    -2(a4,d3.w),(a1)
  593.         bset    #15,(a1)
  594.         move.b    #$ff,2(a1)
  595.         moveq    #0,d3
  596.         move.b    1(a2),d3
  597.         lsr.b    #4,d3
  598.         and.b    #15,d3
  599.         tst.b    d3
  600.         bne.b    bpskip5
  601.         move.b    3(a1),d3 
  602. bpskip5     move.b    1(a2),d4
  603.         and.b    #15,d4
  604.         cmpi.b    #10,d4             ;option 10
  605.         bne.b    bp_do2
  606.         move.b    2(a2),d4
  607.         and.b    #15,d4
  608.         bne.b    bp_not2
  609. bp_do2        add.b    SMON_ST(a5),d3
  610. bp_not2        cmp.w    #1,8(a1)
  611.         beq.b    bpsamplechange
  612.         cmp.b    3(a1),d3
  613.         beq.b    bpoptionals
  614. bpsamplechange    move.b    d3,3(a1)
  615.         or.w    d7,SMON_DMA(a5)
  616.  
  617. bpoptionals     moveq    #0,d3
  618.         moveq    #0,d4
  619.         move.b    1(a2),d3
  620.         and.b    #15,d3
  621.         move.b    2(a2),d4
  622.  
  623.         cmp.b    #0,d3            ; Optionals Here
  624.         bne.b    notopt0
  625.         move.b    d4,11(a1)
  626.  
  627. notopt0        cmp.b    #1,d3
  628.         bne.b    bpskip3
  629.         move.b    d4,2(a1)         ; Volume ook in BPCurrent
  630.         move.w    d4,NPC_Volume(a3)
  631.         bset    #NPCFB_Volume,(a3)
  632.  
  633. bpskip3        cmp.b    #2,d3              ; Set Speed
  634.         bne.b    bpskip9
  635.         move.b    d4,SMON_BPCount(a5)
  636.         move.b    d4,SMON_BPDelay(a5)
  637.  
  638. bpskip9        cmp.b    #3,d3             ; Filter = LED control
  639.         bne.b    bpskipa
  640.         tst.b    d4
  641.         bne.b    bpskipb
  642.         bset    #1,$bfe001
  643.         bra.b    bpskip2
  644. bpskipb        bclr    #1,$bfe001
  645.  
  646. bpskipa        cmp.b    #4,d3             ; PortUp
  647.         bne.b    noportup
  648.         sub.w    d4,(a1)            ; Slide data in BPCurrent
  649.         clr.b    11(a1)             ; Arpeggio's uit
  650.  
  651. noportup    cmp.b    #5,d3             ; PortDown
  652.         bne.b    noportdn
  653.         add.w    d4,(a1)            ; Slide down
  654.         clr.b    11(a1)
  655.  
  656. noportdn    cmp.b    #6,d3            ; SetRepCount
  657.         bne.b    notopt6
  658.         move.b    d4,SMON_BPRepCount(a5)
  659.  
  660. notopt6        cmp.b    #7,d3            ; DBRA repcount
  661.         bne.b    notopt7
  662.         subq.b    #1,SMON_BPRepCount(a5)
  663.         beq.b    notopt7
  664.         cmp.w    SMON_BPStep(a5),d4
  665.         bge.b    jump
  666.         move.l    SMON_Global(a5),a2
  667.         move.l    APG_SendMsg(a2),a2
  668.         move.w    #MSG_NextMod,d2
  669.         jsr    (a2)            ;Send Next Module Message
  670. jump        move.w    d4,SMON_BPStep(a5)
  671.  
  672. notopt7        cmp.b    #8,d3            ;Set AutoSlide
  673.         bne.b    notopt8
  674.         move.b    d4,12(a1)
  675.  
  676. notopt8        cmp.b    #9,d3            ;Set AutoArpeggio
  677.         bne.b    notopt9
  678.         move.b    d4,13(a1)
  679.  
  680. notopt9
  681. bpskip2        lea    NPChannel_SIZEOF(a3),a3
  682.         lea    $20(a1),a1
  683.         asl.w    #1,d7
  684.         dbra    d0,bploop3
  685.  
  686.         addq.b    #3,SMON_BPPatCount(a5)
  687.         cmp.b    #48,SMON_BPPatCount(a5)
  688.         bne.b    bpskip8
  689.         move.b    #0,SMON_BPPatCount(a5)
  690.         addq.w    #1,SMON_BPStep(a5)
  691.  
  692.         move.l    SMON_Global(a5),a2
  693.         move.l    APG_SendMsg(a2),a2
  694.         move.w    #MSG_NextPos,d2
  695.         jsr    (a2)            ;Send Next Position Message
  696.  
  697.         move.l    SMON_Module(a5),a0
  698.         move.w    30(a0),d1
  699.         cmp.w    SMON_BPStep(a5),d1
  700.         bne.b    bpskip8
  701.         move.w    #0,SMON_BPStep(a5)
  702.  
  703.         move.l    SMON_Global(a5),a2
  704.         move.l    APG_SendMsg(a2),a2
  705.         move.w    #MSG_NextMod,d2
  706.         jsr    (a2)            ;Send Next Module Message
  707. bpskip8        rts
  708.  
  709. bpplayit    bclr    #7,(a2)
  710.         tst.l    (a5)             ;Was EG used
  711.         beq.b    noeg1             ;No ??
  712.         moveq    #0,d3             ;Well then copy
  713.         move.l    (a5),a4            ;Old waveform back
  714.         moveq    #7,d7             ;to waveform tables
  715. eg1loop        move.l    4(a5,d3.w),(a4)+    ;Copy...
  716.         addq.w    #4,d3             ;Copy...
  717.         dbra    d7,eg1loop        ;Copy...
  718.  
  719. noeg1        move.w    (a2),NPC_Period(a1)    ;Period from bpcurrent
  720.         bset    #NPCFB_Period,(a1)
  721.  
  722.         moveq    #0,d7
  723.         move.b    3(a2),d7        ;Instrument number
  724.         move.l    d7,d6             ;Also in d6
  725.         lsl.l    #5,d7             ;Header offset
  726.         move.l    4(sp),a3
  727.         move.l    SMON_Module(a3),a3
  728.         cmp.b    #$ff,(a3,d7.w)        ;Is synthetic
  729.         beq.w    bpplaysynthetic        ;Yes ??
  730.         clr.l    (a5)             ;EG Off
  731.         clr.b    $1a(a2)            ;Synthetic mode off
  732.         clr.w    $1e(a2)            ;Lfo Off
  733.         add.l    #24,d7             ;24 is name->ignore
  734.         lsl.l    #2,d6             ;x4 for sample offset
  735.         move.l    4(sp),a4
  736.         lea    SMON_Samples(a4),a4
  737.         move.l    -4(a4,d6),d4        ;Fetch sample pointer
  738.         beq.b    bp_nosamp        ;is zero->no sample
  739.  
  740.         move.l    d4,NPC_Start(a1)    ;Sample pointer in hardware
  741.         move.w    (a3,d7.w),NPC_Length+2(a1);length in hardware
  742.         move.b    2(a2),NPC_Volume+1(a1)
  743.         or.b    #NPCF_Sample!NPCF_WordLength!NPCF_Volume,(a1)
  744.  
  745.         cmp.b    #$ff,2(a2)        ;Use default volume
  746.         bne.b    skipxx             ;No ??
  747.         move.w    6(a3,d7.w),NPC_Volume(a1)
  748.         bset    #NPCFB_Volume,(a1)
  749.  
  750. skipxx         move.w    4(a3,d7.w),8(a2)    ;Length in bpcurrent
  751.         moveq    #0,d6
  752.         move.w    2(a3,d7.w),d6        ;Calculate repeat
  753.         add.l    d6,d4
  754.         move.l    d4,4(a2)        ;sample start in bpcurrent
  755.         cmp.w    #1,8(a2)        ;has sample repeat part
  756.         bne.b    bpskip6            ;Yes ??
  757. bp_nosamp    move.l    4(sp),a0
  758.         move.l    SMON_Global(a0),a0
  759.         move.l    APG_NullSample(a0),4(a2);Play no sample
  760.  
  761. bpskip6        move.w    8(a2),NPC_LoopLength+2(a1);Length to hardware
  762.         move.l    4(a2),NPC_LoopStart(a1)    ;pointer to hardware
  763.         or.b    #NPCF_Loop!NPCF_WordLength,(a1)
  764. bpskip10    or.w    #$8000,d1        ;Turn on DMA for this voice
  765.         rts
  766.  
  767. bpplaysynthetic    move.b    #$1,$1a(a2)        ;Synthetic mode on
  768.         clr.w    $e(a2)             ;EG Pointer restart
  769.         clr.w    $10(a2)         ;LFO Pointer restart
  770.         clr.w    $12(a2)         ;ADSR Pointer restart
  771.         move.w    22(a3,d7.w),$14(a2)    ;EG Delay
  772.         addq.w    #1,$14(a2)        ;0 is nodelay
  773.         move.w    14(a3,d7.w),$16(a2)    ;LFO Delay
  774.         addq.w    #1,$16(a2)        ;So I need correction
  775.         move.w    #1,$18(a2)        ;ADSR Delay->Start immediate
  776.         move.b    17(a3,d7.w),$1d(a2)    ;EG OOC
  777.         move.b    9(a3,d7.w),$1e(a2)    ;LFO OOC
  778.         move.b    4(a3,d7.w),$1f(a2)    ;ADSR OOC
  779.         move.b    19(a3,d7.w),$1c(a2)    ;Current EG Value
  780.         move.l    4(sp),a4
  781.         move.l    SMON_Tables(a4),a4    ; so far so good,now what ??
  782.         moveq    #0,d3            ;Pointer to waveform tables
  783.         move.b    1(a3,d7.w),d3        ;Which waveform
  784.         lsl.l    #6,d3             ;x64 is length waveform table
  785.         add.l    d3,a4
  786.  
  787.         move.l    a4,NPC_Start(a1)    ;Sample Pointer
  788.         move.l    a4,NPC_LoopStart(a1)
  789.         move.l    a4,4(a2)        ;In bpcurrent
  790.         move.w    2(a3,d7.w),NPC_Length+2(a1);Length in words
  791.         move.w    2(a3,d7.w),NPC_LoopLength+2(a1)
  792.         move.w    2(a3,d7.w),8(a2)    ;Length in bpcurrent
  793.         or.b    #NPCF_Sample!NPCF_Loop!NPCF_WordLength,(a1)
  794.  
  795.         tst.b    4(a3,d7.w)        ;Is ADSR on
  796.         beq.b    bpadsroff        ;No ??
  797.         move.l    4(sp),a4
  798.         move.l    SMON_Tables(a4),a4    ;Tables
  799.         moveq    #0,d3
  800.         move.b    5(a3,d7.w),d3        ;ADSR table number
  801.         lsl.l    #6,d3             ;x64 for length
  802.         add.l    d3,a4             ;Add it
  803.         moveq    #0,d3
  804.         move.b    (a4),d3         ;Get table value
  805.         add.b    #128,d3         ;I want it from 0..255
  806.         lsr.w    #2,d3             ;Divide by 4->0..63
  807.         cmp.b    #$ff,2(a2)
  808.         bne.b    bpskip99
  809.         move.b    25(a3,d7.w),2(a2)
  810.  
  811. bpskip99    moveq    #0,d4
  812.         move.b    2(a2),d4        ;Default volume
  813.         mulu    d4,d3             ;default maal init volume
  814.         lsr.w    #6,d3             ;divide by 64
  815.         move.w    d3,NPC_Volume(a1)
  816.         bset    #NPCFB_Volume,(a1)
  817.         bra.b    bpflipper
  818.  
  819. bpadsroff    move.b    2(a2),NPC_Volume+1(a1)
  820.         bset    #NPCFB_Volume,(a1)
  821.  
  822.         cmp.b    #$ff,2(a2)
  823.         bne.b    bpflipper        ;No ADSR
  824.         move.b    25(a3,d7.w),NPC_Volume+1(a1)
  825.         bset    #NPCFB_Volume,(a1)
  826.  
  827. bpflipper    move.l    4(a2),a4        ;Pointer on waveform
  828.         move.l    a4,(a5)            ;Save it
  829.         moveq    #0,d3             ;Save Old waveform
  830.         moveq    #7,d4             ;data in bpbuffer
  831. eg2loop        move.l    (a4,d3.w),4(a5,d3.w)
  832.         addq.w    #4,d3             ;Copy         
  833.         dbra    d4,eg2loop
  834.  
  835.         tst.b    17(a3,d7.w)        ;EG off
  836.         beq.w    bpskip10        ;Yes ??
  837.         tst.b    19(a3,d7.w)        ;Is there an init value for EG
  838.         beq.w    bpskip10        ;No ??
  839.         moveq    #0,d3
  840.         move.b    19(a3,d7.w),d3
  841.         lsr.l    #3,d3             ;Divide by 8 ->0..31
  842.         move.b    d3,$1c(a2)        ;Current EG Value
  843.         subq.l    #1,d3             ;-1,DBRA correction
  844. eg3loop        neg.b    (a4)+
  845.         dbra    d3,eg3loop
  846.         bra.w    bpskip10
  847.  
  848. bpplayarp    lea    bpper(pc),a4
  849.         ext.w    d4
  850.         asl.w    #1,d4
  851.         move.w    -2(a4,d4.w),NPC_Period(a1)
  852.         bset    #NPCFB_Period,(a1)
  853.         rts
  854.  
  855. bpsynth        move.l    a5,-(sp)
  856.         moveq    #3,d0
  857.         lea    SMON_BPCurrent(a5),a2
  858.         move.l    SMON_NoteStruct(a5),a1
  859.         move.l    SMON_Module(a5),a3
  860.         lea    SMON_BPBuffer(a5),a5
  861. bpsynthloop    tst.b    $1a(a2)            ;Is synthetic sound
  862.         beq.b    bpnosynth        ;No ??
  863.         bsr.b    bpyessynth        ;Yes         
  864. bpnosynth    lea    $24(a5),a5
  865.         lea    $20(a2),a2
  866.         lea    NPChannel_SIZEOF(a1),a1
  867.         dbra    d0,bpsynthloop
  868.         move.l    (sp)+,a5
  869.         rts
  870.  
  871. bpyessynth    moveq    #0,d7
  872.         move.b    3(a2),d7        ;Which instr. was I playing
  873.         lsl.w    #5,d7             ;x32, is length of instr.
  874.         tst.b    $1f(a2)         ;ADSR off
  875.         beq.b    bpendadsr        ;Yes ??
  876.         subq.w    #1,$18(a2)        ;Delay,May I
  877.         bne.b    bpendadsr        ;No ??
  878.         moveq    #0,d3
  879.         move.b    8(a3,d7.w),d3
  880.         move.w    d3,$18(a2)        ;Reset Delay Counter
  881.         move.l    4(sp),a4
  882.         move.l    SMON_Tables(a4),a4
  883.         move.b    5(a3,d7.w),d3        ;Which ADSR table
  884.         lsl.l    #6,d3             ;x64
  885.         add.l    d3,a4             ;This is my table
  886.         move.w    $12(a2),d3        ;Get ADSR table pointer
  887.         moveq    #0,d4
  888.         move.b    (a4,d3.w),d4        ;Value from table
  889.         add.b    #128,d4         ;Want it from 0..255
  890.         lsr.w    #2,d4             ;And now from 0..63
  891.         moveq    #0,d3
  892.         move.b    2(a2),d3        ;Current Volume
  893.         mulu    d3,d4             ;MultiPly with table volume
  894.         lsr.w    #6,d4             ;Divide by 64=New volume
  895.  
  896.         move.w    d4,NPC_Volume(a1)
  897.         bset    #NPCFB_Volume,(a1)
  898.  
  899.         addq.w    #1,$12(a2)        ;Increment of ADSR pointer
  900.         move.w    6(a3,d7.w),d4        ;Length of adsr table
  901.         cmp.w    $12(a2),d4        ;End of table reached
  902.         bne.b    bpendadsr        ;No ??
  903.         clr.w    $12(a2)         ;Clear ADSR Pointer
  904.         cmp.b    #1,$1f(a2)        ;Once
  905.         bne.b    bpendadsr        ;No ??
  906.         clr.b    $1f(a2)            ;ADSR off
  907. bpendadsr    tst.b    $1e(a2)            ;LFO On
  908.         beq.b    bpendlfo        ;No ??
  909.         subq.w    #1,$16(a2)        ;LFO delay,May I
  910.         bne.b    bpendlfo        ;No
  911.         moveq    #0,d3
  912.         move.b    16(a3,d7.w),d3
  913.         move.w    d3,$16(a2)        ;Set LFO Count
  914.         move.l    4(sp),a4
  915.         move.l    SMON_Tables(a4),a4
  916.         move.b    10(a3,d7.w),d3        ;Which LFO table
  917.         lsl.l    #6,d3             ;x64
  918.         add.l    d3,a4
  919.         move.w    $10(a2),d3        ;LFO pointer
  920.         moveq    #0,d4
  921.         move.b    (a4,d3.w),d4        ;That's my value
  922.         ext.w    d4             ;Make it a word
  923.         ext.l    d4             ;And a longword
  924.         moveq    #0,d5
  925.         move.b    11(a3,d7.w),d5        ;LFO depth
  926.         tst.b    d5
  927.         beq.b    bpnotx
  928.         divs    d5,d4             ;Calculate it
  929. bpnotx        move.w    (a2),d5         ;Period
  930.         add.w    d4,d5             ;New Period
  931.         move.w    d5,NPC_Period(a1)    ;In hardware
  932.         bset    #NPCFB_Period,(a1)
  933.         addq.w    #1,$10(a2)        ;Next position
  934.         move.w    12(a3,d7.w),d3        ;LFO table Length
  935.         cmp.w    $10(a2),d3        ;End Reached
  936.         bne.b    bpendlfo        ;NO ??
  937.         clr.w    $10(a2)             ;Reset LFO Pointer
  938.         cmp.b    #1,$1e(a2)        ;Once LFO
  939.         bne.b    bpendlfo        ;NO ??
  940.         clr.b    $1e(a2)         ;LFO Off
  941. bpendlfo    tst.b    $1d(a2)         ;EG On
  942.         beq.w    bpendeg            ;No ??
  943.         subq.w    #1,$14(a2)        ;EG delay,May I
  944.         bne.w    bpendeg         ;No
  945.         tst.l    (a5)
  946.         beq.b    bpendeg
  947.         moveq    #0,d3
  948.         move.b    24(a3,d7.w),d3
  949.         move.w    d3,$14(a2)        ;Set EG Count
  950.         move.l    4(sp),a4
  951.         move.l    SMON_Tables(a4),a4
  952.         move.b    18(a3,d7.w),d3        ;Which EG table
  953.         lsl.l    #6,d3             ;x64
  954.         add.l    d3,a4
  955.         move.w    $e(a2),d3        ;EG pointer
  956.         moveq    #0,d4
  957.         move.b    (a4,d3.w),d4        ;That's my value
  958.         move.l    (a5),a4         ;Pointer to waveform
  959.         add.b    #128,d4         ;0..255
  960.         lsr.l    #3,d4             ;0..31
  961.         moveq    #0,d3
  962.         move.b    $1c(a2),d3        ;Old EG Value
  963.         move.b    d4,$1c(a2)
  964.         add.l    d3,a4             ;WaveForm Position
  965.         move.l    a5,a6             ;Buffer
  966.         add.l    d3,a6             ;Position
  967.         addq.l    #4,a6             ;For adress in buffer
  968.         cmp.b    d3,d4             ;Compare old with new value
  969.         beq.b    bpnexteg        ;no change ??
  970.         bgt.b    bpishigh        ;new value is higher
  971. bpislow        sub.l    d4,d3             ;oldvalue-newvalue
  972.         subq.l    #1,d3             ;Correction for DBRA
  973. bpegloop1a    move.b    -(a6),d4
  974.         move.b    d4,-(a4)
  975.         dbra    d3,bpegloop1a
  976.         bra.b    bpnexteg
  977.  
  978. bpishigh    sub.l    d3,d4             ;Newvalue-oldvalue
  979.         subq.l    #1,d4             ;Correction for DBRA
  980. bpegloop1b    move.b    (a6)+,d3
  981.         neg.b    d3
  982.         move.b    d3,(a4)+        ;DoIt
  983.         dbra    d4,bpegloop1b
  984.  
  985. bpnexteg    addq.w    #1,$e(a2)        ;Next position
  986.         move.w    20(a3,d7.w),d3        ;EG table Length
  987.         cmp.w    $e(a2),d3        ;End Reached
  988.         bne.b    bpendeg            ;NO ??
  989.         clr.w    $e(a2)             ;Reset EG Pointer
  990.         cmp.b    #1,$1d(a2)        ;Once EG
  991.         bne.b    bpendeg         ;NO ??
  992.         clr.b    $1d(a2)         ;EG Off
  993. bpendeg        rts
  994. ;------------------------------------------------------------------------------
  995.     dc.w 6848,6464,6080,5760,5440,5120,4832,4576,4320,4064,3840,3616
  996.     dc.w 3424,3232,3040,2880,2720,2560,2416,2288,2160,2032,1920,1808
  997.     dc.w 1712,1616,1520,1440,1360,1280,1208,1144,1080,1016,0960,0904
  998. bpper    dc.w 0856,0808,0760,0720,0680,0640,0604,0572,0540,0508,0480,0452
  999.     dc.w 0428,0404,0380,0360,0340,0320,0302,0286,0270,0254,0240,0226
  1000.     dc.w 0214,0202,0190,0180,0170,0160,0151,0143,0135,0127,0120,0113
  1001.     dc.w 0107,0101,0095,0090,0085,0080,0076,0072,0068,0064,0060,0057
  1002. ;------------------------------------------------------------------------------
  1003. ; ModuleName
  1004. ;
  1005. ; IN :    A1 = Address
  1006. ;
  1007. ; OUT:    A0 = Pointer To The Name
  1008. ;
  1009.  
  1010. SM_ModuleName
  1011.     move.l    a1,a0
  1012.     rts
  1013. ;------------------------------------------------------------------------------
  1014. ; GetMaxPattern
  1015. ;
  1016. ; IN :    A1 = Address
  1017. ;
  1018. ; OUT:    D1 = Number Of Patterns
  1019. ;
  1020.  
  1021. SM_GetMaxPattern
  1022.     movem.l    d0/d2/a1,-(sp)
  1023.  
  1024.     move.w    30(a1),d0        ;d1 now contains length in steps
  1025.     move.l    #512,d2
  1026.     moveq    #1,d1            ;1 is highest pattern number
  1027.     mulu    #4,d0             ;4 voices per step
  1028.     subq.w    #1,d0             ;correction for DBRA
  1029. .GTMAX1    cmp.w    (a1,d2.l),d1        ;Is it higher
  1030.     bge.b    .gtmax2            ;No
  1031.     move.w    (a1,d2.l),d1        ;Yes, so let D2 be highest
  1032. .GTMAX2    addq.l    #4,d2             ;Next Voice
  1033.     dbra    d0,.gtmax1        ;And search
  1034.  
  1035.     movem.l    (sp)+,d0/d2/a1
  1036.     rts
  1037. ;------------------------------------------------------------------------------
  1038. ; GetMaxSample
  1039. ;
  1040. ; IN :    A1 = Address
  1041. ;
  1042. ; OUT:    D1 = Number Of Samples
  1043. ;
  1044.  
  1045. SM_GetMaxSample
  1046.     moveq    #15,d1
  1047.     rts
  1048. ;------------------------------------------------------------------------------
  1049. ; GetSongLength
  1050. ;
  1051. ; IN :    A1 = Address
  1052. ;
  1053. ; OUT:    D1 = Length
  1054. ;
  1055.  
  1056. SM_GetSongLength
  1057.     move.w    30(a1),d1
  1058.     rts
  1059. ;------------------------------------------------------------------------------
  1060. ; GetSongPos
  1061. ;
  1062. ; IN :    A1 = Address
  1063. ;
  1064. ; OUT:    D1 = Position (0-x)
  1065. ;
  1066.  
  1067. SM_GetSongPos
  1068.     move.l    a0,-(sp)
  1069.     lea    SM_DataArea,a0
  1070.     move.w    SMON_BPStep(a0),d1
  1071.     move.l    (sp)+,a0
  1072.     rts
  1073. ;------------------------------------------------------------------------------
  1074. ; Rewind
  1075. ;
  1076. ; IN :    A1 = Address
  1077. ;
  1078. ; OUT:    D1 = New Position
  1079. ;
  1080.  
  1081. SM_Rewind
  1082.     movem.l    a0-a1,-(sp)
  1083.     lea    SM_DataArea,a0
  1084.  
  1085.     move.w    SMON_BPStep(a0),d1
  1086.     beq.b    sforwa1
  1087.     subq.w    #1,d1
  1088.     bra.b    sforwa1
  1089. ;------------------------------------------------------------------------------
  1090. ; Forward
  1091. ;
  1092. ; IN :    A1 = Address
  1093. ;
  1094. ; OUT:    D1 = New Position
  1095. ;
  1096.  
  1097. SM_Forward
  1098.     movem.l    a0-a1,-(sp)
  1099.     lea    SM_DataArea,a0
  1100.  
  1101.     move.w    SMON_BPStep(a0),d1
  1102.     addq.w    #1,d1
  1103.     cmp.w    30(a1),d1
  1104.     blt.b    sforwa1
  1105.     moveq    #0,d1
  1106.  
  1107. SFORWA1    move.w    d1,SMON_BPStep(a0)
  1108.     clr.b    SMON_BPPatCount(a0)
  1109.  
  1110.     movem.l    (sp)+,a0-a1
  1111.     rts
  1112. ;------------------------------------------------------------------------------
  1113.     SECTION    SM_DataArea,BSS
  1114.  
  1115. SM_DataArea
  1116.     ds.b    SoundMonStruct_SIZEOF
  1117. ;------------------------------------------------------------------------------
  1118. SLUT
  1119.